package m.jclecai.com.view;

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ViewSwitcher;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;

import m.jclecai.com.R;

/**
 * 程序加载视图
 */
public class XLoading implements View.OnClickListener {

    private View mTargetView;
    private OnRetryClickListener mClickListener;
    private Context mContext;
    private LayoutInflater mInflater;
    private RelativeLayout mContainer;
    private ArrayList<View> mCustomViews;
    private ArrayList<View> mDefaultViews;
    private ViewSwitcher mSwitcher;
    private AnimationDrawable anim = null;

    // Default Tags
    private final String TAG_INTERNET_OFF = "INTERNET_OFF";
    private final String TAG_LOADING_CONTENT = "LOADING_CONTENT";
    private final String TAG_OTHER_EXCEPTION = "OTHER_EXCEPTION";

    private final String[] mSupportedAbsListViews = new String[]{
            "listview",
            "gridview",
            "expandablelistview"
    };
    private final String[] mSupportedViews = new String[]{
            "webview",
            "pulltorefreshlistview",
            "pulltorefreshadapterviewbase",
            "linearlayout",
            "relativelayout",
            "framelayout",
            "scrollview",
            "recyclerview",
            "viewgroup",
            "autoswiperefreshlayout"
    };

    public interface OnRetryClickListener {
        void OnRetry(String btnMessage);
    }

    public XLoading(Context context, View targetView) {
        removeView();
        this.mContext = context;
        this.mInflater = ((Activity) mContext).getLayoutInflater();
        this.mTargetView = targetView;
        this.mContainer = new RelativeLayout(mContext);
        this.mCustomViews = new ArrayList<>();
        this.mDefaultViews = new ArrayList<>();
        initViews();
    }

    public XLoading(Context context, int viewID) {
        removeView();
        this.mContext = context;
        this.mInflater = ((Activity) mContext).getLayoutInflater();
        this.mTargetView = mInflater.inflate(viewID, null, false);
        this.mContainer = new RelativeLayout(mContext);
        this.mCustomViews = new ArrayList<>();
        this.mDefaultViews = new ArrayList<>();
        initViews();
    }


    void initViews() {
        Class viewClass = mTargetView.getClass();
        Class superViewClass = viewClass.getSuperclass();
        String viewType = viewClass.getName().substring(viewClass.getName().lastIndexOf('.') + 1).toLowerCase(Locale.getDefault());
        String superViewType = superViewClass.getName().substring(superViewClass.getName().lastIndexOf('.') + 1).toLowerCase(Locale.getDefault());

        if (Arrays.asList(mSupportedAbsListViews).contains(viewType) || Arrays.asList(mSupportedAbsListViews).contains(superViewType))
            initializeAbsListView();
        else if (Arrays.asList(mSupportedViews).contains(viewType) || Arrays.asList(mSupportedViews).contains(superViewType))
            initializeViewContainer();
        else
            throw new IllegalArgumentException("视图类型 [" + superViewType + "] 暂不支持 !");
    }

    private void initializeViewContainer() {

        setDefaultViews();

        mSwitcher = new ViewSwitcher(mContext);
        ViewSwitcher.LayoutParams params = new ViewSwitcher.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mSwitcher.setLayoutParams(params);

        ViewGroup group = (ViewGroup) mTargetView.getParent();
        int index = 0;
        Clonner target = new Clonner(mTargetView);
        if (group != null) {
            index = group.indexOfChild(mTargetView);
            group.removeView(mTargetView);

        }

        mSwitcher.addView(mContainer, 0);
        mSwitcher.addView(target.getmView(), 1);
        mSwitcher.setDisplayedChild(1);

        if (group != null) {
            group.addView(mSwitcher, index);
        } else {
            ((Activity) mContext).setContentView(mSwitcher);
        }
    }

    private void setDefaultViews() {
        View mLayoutInternetOff = initView(R.layout.view_exception_no_internet, TAG_INTERNET_OFF);
        View mLayoutLoadingContent = initView(R.layout.view_exception_loading_content, TAG_LOADING_CONTENT);
        View mLayoutOther = initView(R.layout.view_exception_failure, TAG_OTHER_EXCEPTION);

        mDefaultViews.add(0, mLayoutInternetOff);
        mDefaultViews.add(1, mLayoutLoadingContent);
        mDefaultViews.add(2, mLayoutOther);

        // Hide all layouts at first initialization
        mLayoutInternetOff.setVisibility(View.GONE);
        mLayoutLoadingContent.setVisibility(View.GONE);
        mLayoutOther.setVisibility(View.GONE);

        // init Layout params
        RelativeLayout.LayoutParams containerParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        containerParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
        containerParams.addRule(RelativeLayout.CENTER_VERTICAL);

        // init new RelativeLayout Wrapper
        mContainer.setLayoutParams(containerParams);

        // Add default views
        mContainer.addView(mLayoutLoadingContent);
        mContainer.addView(mLayoutInternetOff);
        mContainer.addView(mLayoutOther);
    }

    private void initializeAbsListView() {

        setDefaultViews();

        AbsListView abslistview = (AbsListView) mTargetView;
        abslistview.setVisibility(View.GONE);
        ViewGroup parent = (ViewGroup) abslistview.getParent();
        if (mContainer != null) {
            parent.addView(mContainer);
            abslistview.setEmptyView(mContainer);
        } else
            throw new IllegalArgumentException("mContainer is null !");

    }

    public void showLoadingLayout() {
        show(TAG_LOADING_CONTENT);
    }

    public void showInternetOffLayout(String message) {
        show(TAG_INTERNET_OFF,message);
    }

    public void showExceptionLayout(String message) {
        show(TAG_OTHER_EXCEPTION,message);
    }

    public void showCustomView(String tag) {
        show(tag);
    }

    public void hideAll() {
        ArrayList<View> views = new ArrayList<>(mDefaultViews);
        views.addAll(mCustomViews);
        for (View view : views) {
            view.setVisibility(View.GONE);
        }
        if (mSwitcher != null) {
            mSwitcher.setDisplayedChild(1);
        }
    }

    private void show(String tag) {
        show(tag, null);
    }

    private void show(String tag, String message) {
        ArrayList<View> views = new ArrayList<>(mDefaultViews);
        views.addAll(mCustomViews);
        for (View view : views) {
            if (view.getTag() != null && view.getTag().toString().equals(tag)) {
//                if(view.getTag().toString().equals(TAG_LOADING_CONTENT)) {
//                    if(anim != null) {
//                        anim.stop();
//                        anim = null;
//                    }
//                    anim = (AnimationDrawable) view.findViewById(R.id.mIvLoading).getBackground();
//                    anim.start();
//                }
                view.setVisibility(View.VISIBLE);
                if(message != null)
                view.findViewById(R.id.exception_button).setTag(message);
            } else {
                view.setVisibility(View.GONE);
            }
        }
        if (mSwitcher != null && mSwitcher.getDisplayedChild() != 0) {
            mSwitcher.setDisplayedChild(0);
        }
    }

    /**
     * Return a view based on layout id
     *
     * @param layout Layout Id
     * @param tag    Layout Tag
     * @return View
     */
    private View initView(int layout, String tag) {
        View view = mInflater.inflate(layout, null, false);

        view.setTag(tag);
        view.setVisibility(View.GONE);

        View buttonView = view.findViewById(R.id.exception_button);
        if (buttonView != null)
            buttonView.setOnClickListener(this);

        return view;
    }


    public void setLoadingButtonMessage(String message) {
        if(!TextUtils.isEmpty(message))
        ((TextView) mDefaultViews.get(1).findViewById(R.id.exception_button)).setText(message);
    }

    public void setInternetOffButtonMessage(String message) {
        if(!TextUtils.isEmpty(message))
        ((TextView) mDefaultViews.get(0).findViewById(R.id.exception_button)).setText(message);
    }

    public void setOtherExceptionButtonMessage(String message) {
        if(!TextUtils.isEmpty(message))
        ((TextView) mDefaultViews.get(2).findViewById(R.id.exception_button)).setText(message);
    }

    public void setLoadingMessage(String message) {
        if(!TextUtils.isEmpty(message))
        ((TextView) mDefaultViews.get(1).findViewById(R.id.exception_message)).setText(message);
    }

    public void setInternetOffMessage(String message) {
        if(!TextUtils.isEmpty(message))
        ((TextView) mDefaultViews.get(0).findViewById(R.id.exception_message)).setText(message);
    }

    public void setOtherExceptionMessage(String message) {
        if(!TextUtils.isEmpty(message))
        ((TextView) mDefaultViews.get(2).findViewById(R.id.exception_message)).setText(message);
    }

    public void setOnRetryListener(OnRetryClickListener clickListener) {
        this.mClickListener = clickListener;
    }

    public void setExceptionIcon(int resId){
        ((ImageView) mDefaultViews.get(2).findViewById(R.id.imageView)).setImageResource(resId);
    }

    public void addCustomView(View customView, String tag) {
        customView.setTag(tag);
        customView.setVisibility(View.GONE);
        mCustomViews.add(customView);
        mContainer.addView(customView);
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.exception_button) {
            if (mClickListener != null)
                mClickListener.OnRetry(view.getTag() != null ? view.getTag().toString() : "");
        }
    }

    private class Clonner {
        private View mView;

        public Clonner(View view) {
            this.setmView(view);
        }

        public View getmView() {
            return mView;
        }

        public void setmView(View mView) {
            this.mView = mView;
        }
    }

    public void removeView() {
        if (mTargetView != null)
            ((ViewGroup) mTargetView).removeAllViews();
        if (mContainer != null)
            mContainer.removeAllViews();
        if (mCustomViews != null)
            mCustomViews.clear();
        if (mDefaultViews != null)
            mDefaultViews.clear();
        if (mSwitcher != null)
            mSwitcher.removeAllViews();

        this.mContext = null;
        this.mInflater = null;
        this.mTargetView = null;
        this.mContainer = null;
        this.mCustomViews = null;
        this.mDefaultViews = null;
    }


    public void showExceptButton(boolean bool) {
        for (int i = 0; i < mDefaultViews.size(); i++) {
            View viewById = mDefaultViews.get(i).findViewById(R.id.exception_button);
            if (viewById != null)
                viewById.setVisibility(bool ? View.VISIBLE : View.GONE);
        }
    }

}